package com.east.webtop.auth;

import java.util.HashMap;
import java.util.Map;

import com.laszlosystems.webtop.core.session.Session;
import com.laszlosystems.webtop.core.session.SessionAttributes;
import com.laszlosystems.webtop.core.user.AuthenticationResult;
import com.laszlosystems.webtop.core.user.AuthenticationResultImpl;
import com.laszlosystems.webtop.user.dao.AuthenticationDao;
import com.laszlosystems.webtop.user.dao.TokenGenerator;

public class CustomAuthenticationDao implements AuthenticationDao {

    private final TokenGenerator tokenGenerator;

    public CustomAuthenticationDao(TokenGenerator tokenGenerator) {
        this.tokenGenerator = tokenGenerator;
    }
    
    public AuthenticationResult authenticate(String username, String password, Map<String, String> attributes) {
        return authenticate(username, password, tokenGenerator.generateToken(username));
    }
    
    public AuthenticationResult authenticate(String loginName, String password, String token) {
        AuthenticationResult result = AuthenticationResultImpl.createAuthenticated(loginName, tokenGenerator.generateToken(loginName));        
        if (result.isAuthenticated()) {
            result = onNewToken(result, result.getToken());
        }
        return result;
    }

    public AuthenticationResult validateToken(String token) {
        String username = tokenGenerator.getUsername(token);
        if (username == null) {
            return AuthenticationResultImpl.createUnauthenticated();
        }

        try {
            return authenticate(username, "", token);
        }
        catch (Throwable t) {
            return AuthenticationResultImpl.createUnauthenticated();
        }
    }

    public String refreshToken(Session session) {
    	String token = session.getToken();
        if (token != null) {
            onTokenChange(session, token);
        }
        return token;
    }

    public boolean supportsAuthenticate() {
        return true;
    }

    public boolean supportsValidateToken() {
        return true;
    }

    private AuthenticationResult onNewToken(AuthenticationResult result, String token) {
        Long expiry = tokenGenerator.getExpiry(token);
        if (expiry != null) {
            Map<String, Object> attrs = new HashMap<String, Object>(result.getSessionAttributes());
            attrs.put(SessionAttributes.TOKEN_EXPIRY_TIME, expiry);
            result = AuthenticationResultImpl.createAuthenticated(result.getUsername(),
                    result.getToken(), result.getEmail(), attrs);
        }else{
            Map<String, Object> attrs = new HashMap<String, Object>(result.getSessionAttributes());
            attrs.put(SessionAttributes.TOKEN_EXPIRY_TIME, 1000000);
            result = AuthenticationResultImpl.createAuthenticated(result.getUsername(),
                    result.getToken(), result.getEmail(), attrs);
        }
        return result;
    }

    private void onTokenChange(Session session, String token) {
        Long expiry = tokenGenerator.getExpiry(token);
        System.out.println("expiry time: "+expiry);
        if (expiry != null) {
            session.setAttribute(SessionAttributes.TOKEN_EXPIRY_TIME, expiry);
        }else{
        	session.setAttribute(SessionAttributes.TOKEN_EXPIRY_TIME, 1000000);
        }
    }

}
